package com.piggy.core.socket.handler;

import com.alibaba.fastjson2.JSONObject;
import com.piggy.core.executor.Executor;
import com.piggy.core.executor.impl.DubboExecutor;
import com.piggy.core.executor.impl.HttpExecutor;
import com.piggy.core.model.HttpStatement;
import com.piggy.core.mybatis.factory.MybatisSqlSessionFactory;
import com.piggy.core.mybatis.mapper.ApplicationInterfaceMethod;
import com.piggy.core.parser.RequestParser;
import com.piggy.core.utils.HttpStatementUtil;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.codec.http.*;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

public class GatewayForwardHandler extends ChannelInboundHandlerAdapter {
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws IOException {
        Channel channel = ctx.channel();
        FullHttpRequest request = (FullHttpRequest) msg;
        RequestParser requestParser = new RequestParser(request);
        String uri = requestParser.getUri();
        if(uri != null){
            if(uri.equals("/favicon.ico")){
                FullHttpResponse response = new DefaultFullHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
                Path path = Paths.get("D:\\code\\dubbo-gateway\\gateway-core-1022\\src\\main\\resources\\static\\favicon.ico");
                response.content().writeBytes(Files.readAllBytes(path));
                HttpHeaders headers = response.headers();
                headers.set(HttpHeaderNames.CONTENT_TYPE, "image/x-icon");
                headers.set(HttpHeaderNames.CONTENT_LENGTH, response.content().readableBytes());
                ctx.channel().writeAndFlush(response);
            }else{
                HttpStatement httpStatement = HttpStatementUtil.getHttpStatement(uri);
                if(httpStatement == null){
                    SqlSessionFactory sqlSessionFactory = MybatisSqlSessionFactory.getSqlSessionFactory();
                    SqlSession sqlSession = sqlSessionFactory.openSession();
                    ApplicationInterfaceMethod mapper = sqlSession.getMapper(ApplicationInterfaceMethod.class);
                    httpStatement = mapper.selectGatewayMethodByUri(uri);
                    sqlSession.close();
                    HttpStatementUtil.putHttpStatement(uri, httpStatement);
                }
                Executor executor;
                switch (httpStatement.getForwardType()){
                    case "dubbo":
                        JSONObject param = requestParser.getParam();
                        executor = new DubboExecutor(httpStatement, param);
                        break;
                    case "http":
                    case "https":
                        executor = new HttpExecutor(request);
                        break;
                    default:
                        throw new RuntimeException();
                }
                executor.execute(channel);
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }
}
